package cn.caskm.souvenirshopsystem.service.impl;

import cn.caskm.souvenirshopsystem.constants.BizConstants;
import cn.caskm.souvenirshopsystem.domain.Result;
import cn.caskm.souvenirshopsystem.domain.dto.PageDTO;
import cn.caskm.souvenirshopsystem.domain.po.*;
import cn.caskm.souvenirshopsystem.domain.query.AdminGoodsQuery;
import cn.caskm.souvenirshopsystem.domain.query.CategoryGoodsQuery;
import cn.caskm.souvenirshopsystem.domain.query.PageQuery;
import cn.caskm.souvenirshopsystem.domain.vo.AdminGoodsListVO;
import cn.caskm.souvenirshopsystem.domain.vo.GoodsDetailVO;
import cn.caskm.souvenirshopsystem.exceptions.BizException;
import cn.caskm.souvenirshopsystem.mapper.GoodsMapper;
import cn.caskm.souvenirshopsystem.mapper.GoodsOrderMapper;
import cn.caskm.souvenirshopsystem.service.AdminUserService;
import cn.caskm.souvenirshopsystem.service.GoodsCategoryService;
import cn.caskm.souvenirshopsystem.service.GoodsCollectService;
import cn.caskm.souvenirshopsystem.service.GoodsService;
import cn.caskm.souvenirshopsystem.utils.UserContext;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements GoodsService {

    private final GoodsCategoryService goodsCategoryService;

    private final AdminUserService adminUserService;

    private final GoodsOrderMapper orderMapper;

    private final GoodsCollectService collectService;

    @Override
    public Result<PageDTO<AdminGoodsListVO>> page(AdminGoodsQuery query) {
        // 获取参数
        Long pageNum = query.getPageNum();
        if (pageNum == null) {
            pageNum = BizConstants.DEFAULT_PAGE_NUM;
        }
        Long pageSize = query.getPageSize();
        if (pageSize == null) {
            pageSize = BizConstants.DEFAULT_PAGE_SIZE;
        }

        // 查询数据
        String goodsName = query.getGoodsName();
        Integer categoryId = query.getCategoryId();
        Page<Goods> page = lambdaQuery()
                .eq(categoryId != null, Goods::getCategoryId, categoryId)
                .like(StrUtil.isNotBlank(goodsName), Goods::getGoodsName, goodsName)
                .eq(Goods::getDeleteStatus, "0") // 只查询未删除的
                .orderByDesc(Goods::getCreateTime)
                .page(new Page<>(pageNum, pageSize));
        List<Goods> goods = page.getRecords();
        if (CollUtil.isEmpty(goods)) {
            return Result.success(PageDTO.empty());
        }

        // 获取分类和用户信息
        Set<Integer> categoryIds = goods.stream().map(Goods::getCategoryId).collect(Collectors.toSet());
        Set<Integer> userIds = goods.stream().map(Goods::getUserId).collect(Collectors.toSet());
        Map<Integer, GoodsCategory> categoryMap = Collections.emptyMap();
        Map<Long, AdminUser> userMap = Collections.emptyMap();
        if (CollUtil.isNotEmpty(categoryIds)) {
            List<GoodsCategory> categories = goodsCategoryService.lambdaQuery()
                    .in(GoodsCategory::getCategoryId, categoryIds)
                    .list();
            if (CollUtil.isEmpty(categories)) {
                throw new BizException("商品类型信息错误");
            }
            categoryMap = categories.stream().collect(Collectors.toMap(GoodsCategory::getCategoryId, c -> c));
        }
        if (CollUtil.isNotEmpty(userIds)) {
            List<AdminUser> users = adminUserService.lambdaQuery()
                    .in(AdminUser::getId, userIds)
                    .list();
            if (CollUtil.isEmpty(users)) {
                throw new BizException("用户信息错误");
            }
            userMap = users.stream().collect(Collectors.toMap(AdminUser::getId, u -> u));
        }

        // 组装vo
        List<AdminGoodsListVO> result = new ArrayList<>(goods.size());
        for (Goods good : goods) {
            AdminUser user = userMap.get(good.getUserId().longValue());
            if (user == null) {
                continue;
            }
            GoodsCategory goodsCategory = categoryMap.get(good.getCategoryId());
            if (goodsCategory == null) {
                continue;
            }
            AdminGoodsListVO item = BeanUtil.copyProperties(good, AdminGoodsListVO.class);
            item.setUserName(user.getUserName());
            item.setCategoryName(goodsCategory.getCategoryName());
            result.add(item);
        }

        // 返回
        return Result.success(PageDTO.of(result, page.getPages(), page.getTotal()));
    }

    @Override
    public Result<List<Goods>> getAll() {
        return Result.success(list());
    }

    @Override
    public Result<Goods> detail(Integer id) {
        Goods goods = getById(id);
        if (goods == null) {
            throw new BizException("商品信息不存在");
        }
        return Result.success(goods);
    }

    @Override
    public void saveOrUpdateEntity(Goods goods) {
        if (goods.getGoodsId() == null) {
            // 新增商品
            goods.setCreateTime(LocalDateTime.now());
            goods.setUserId(UserContext.getUser().intValue());
            goods.setDeleteStatus("0"); // 默认未删除
            goods.setCreateTime(LocalDateTime.now());
            save(goods);
        } else {
            // 修改商品
            updateById(goods);
        }
    }

    @Override
    public Result<PageDTO<Goods>> getRecommendList(PageQuery query) {
        // 查询数据
        Long pageNum = query.getPageNum();
        Long pageSize = query.getPageSize();
        Page<Goods> page = lambdaQuery()
                .eq(Goods::getStatus, "0")
                .eq(Goods::getSetIndex, "1")
                .eq(Goods::getDeleteStatus, "0")
                .orderByDesc(Goods::getCreateTime)
                .page(new Page<>(pageNum, pageSize));
        List<Goods> records = page.getRecords();
        if (CollUtil.isEmpty(records)) {
            return Result.success(PageDTO.empty());
        }
        return Result.success(PageDTO.of(records, page.getPages(), page.getTotal()));
    }

    @Override
    public Result<PageDTO<Goods>> getByCategory(CategoryGoodsQuery query) {
        Integer categoryId = query.getCategoryId();
        // 查询数据
        Long pageNum = query.getPageNum();
        Long pageSize = query.getPageSize();
        Page<Goods> page = lambdaQuery()
                .eq(Goods::getStatus, "0")
                .eq(Goods::getDeleteStatus, "0")
                .eq(Goods::getCategoryId, categoryId)
                .orderByDesc(Goods::getCreateTime)
                .page(new Page<>(pageNum, pageSize));
        List<Goods> records = page.getRecords();
        if (CollUtil.isEmpty(records)) {
            return Result.success(PageDTO.empty());
        }
        return Result.success(PageDTO.of(records, page.getPages(), page.getTotal()));
    }

    @Override
    public Result<GoodsDetailVO> getGoodsDetail(Integer goodsId) {
        // 获取商品信息
        Goods goods = getById(goodsId);
        if (goods == null) {
            throw new BizException("商品信息为空");
        }

        // 获取这个商品下单的数量
        LambdaQueryWrapper<GoodsOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GoodsOrder::getGoodsId, goodsId);
        wrapper.eq(GoodsOrder::getOrderStatus, 3);
        Long sales = orderMapper.selectCount(wrapper);

        // 查询是否收藏
        Long userId = UserContext.getUser();
        Long count;
        if (userId == null) {
            count = 0L;
        } else {
            count = collectService.lambdaQuery()
                    .eq(GoodsCollect::getGoodsId, goodsId)
                    .eq(GoodsCollect::getUserId, userId.intValue())
                    .count();
        }

        // 组装vo
        GoodsDetailVO result = new GoodsDetailVO();
        result.setGoodsId(goodsId);
        result.setDesc(goods.getGoodsDesc());
        result.setImage(goods.getImage());
        result.setPrice(goods.getGoodsPrice());
        result.setSales(sales);
        result.setGoodsName(goods.getGoodsName());
        result.setIfCollect(count > 0);

        return Result.success(result);
    }
}
